//---------------------------------------------------------------------------------
#include <stdio.h>
#include <QtDebug>
#include "CAStar.h"
//---------------------------------------------------------------------------------
CAStar::CAStar(CMap* map) {
	this->map=map;
}
//---------------------------------------------------------------------------------
bool CAStar::goTo(int xSrc, int ySrc, int xDest, int yDest, QList<CMap::EAction> &actions) {	
	this->xDest=xDest;
	this->yDest=yDest;
	
	actions.clear();
	if(xSrc == xDest && ySrc == yDest) {
		return true;
	}
	
	map->getSize(w, h);
	size=w*h;
	buffer=new int[size];
	
	memset(buffer, -1, size*sizeof(int));
	
	buffer[ySrc*w+xSrc]=0;
	
	if(fillBuffer()) {
		int xC, yC;
		int iC;
		
		xC=xDest;
		yC=yDest;
		
		while(xC != xSrc || yC != ySrc) {
			iC=yC*w+xC;
			if(buffer[iC] == buffer[iC-w]+1) {
				yC--;
				actions.insert(0, CMap::eaMoveDown);
			}else if(buffer[iC] == buffer[iC+w]+1) {
				yC++;
				actions.insert(0, CMap::eaMoveUp);
			}else if(buffer[iC] == buffer[iC+1]+1) {
				xC++;
				actions.insert(0, CMap::eaMoveLeft);
			}else if(buffer[iC] == buffer[iC-1]+1) {
				xC--;
				actions.insert(0, CMap::eaMoveRight);
			}
		}
	}
	
	delete[] buffer;
	
	return actions.size() != 0;
}
//---------------------------------------------------------------------------------
bool CAStar::fillBuffer(int curValue) {
	int xC, yC;
	int i;
	bool isMove=false;
	int newValue=curValue+1;
	
	for(i=0;i<size;i++) {
		if(buffer[i] == curValue) {
			int xM, yM;
			int iM;
			bool arrived;
			xC=i%w;
			yC=i/w;
			
			xM=xC;
			yM=yC-1;
			iM=yM*w+xM;
			if(map->canMoveUp(xC, yC) && buffer[iM] < 0) {
				buffer[iM]=newValue;
				if(yM == yDest && xM == xDest) {
					return true;
				}
				isMove=true;
			}
			
			xM=xC;
			yM=yC+1;
			iM=yM*w+xM;
			if(map->canMoveDown(xC, yC) && buffer[iM] < 0) {
				buffer[iM]=newValue;
				if(yM == yDest && xM == xDest) {
					return true;
				}
				isMove=true;
			}
			
			xM=xC+1;
			yM=yC;
			iM=yM*w+xM;
			if(map->canMoveRight(xC, yC) && buffer[iM] < 0) {
				buffer[iM]=newValue;
				if(yM == yDest && xM == xDest) {
					return true;
				}
				isMove=true;
			}
			
			xM=xC-1;
			yM=yC;
			iM=yM*w+xM;
			if(map->canMoveLeft(xC, yC) && buffer[iM] < 0) {
				buffer[iM]=newValue;
				if(yM == yDest && xM == xDest) {
					return true;
				}
				isMove=true;
			}
		}
	}
	
	if(isMove) {
		return fillBuffer(newValue);
	}
	
	return false;
}
//---------------------------------------------------------------------------------
bool CAStar::testMove(int xCur, int yCur, int xPlayer, int yPlayer, int idxBuffer, pCMFunction pFct, int newValue, bool& arrived) {
	arrived=false;
	if((map->*pFct)(xCur, yCur) && buffer[idxBuffer] < 0) {
		buffer[idxBuffer]=newValue;
		if(yPlayer == yDest && xPlayer == xDest) {
			arrived=true;
		}
		return true;
	}
	
	return false;
}
//---------------------------------------------------------------------------------